package com.demo.steammanagement.controller.admin;

import java.io.IOException;
import java.util.UUID;
import java.util.List;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.core.io.InputStreamResource;

import java.io.ByteArrayInputStream;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.demo.steammanagement.common.QueryBuild;
import com.demo.steammanagement.common.ResultMsg;
import com.demo.steammanagement.config.response.BizException;
import com.demo.steammanagement.model.entity.RedeemCodeInfo;
import com.demo.steammanagement.model.vo.RedeemCodeInfoVO;
import com.demo.steammanagement.model.vo.Result;
import com.demo.steammanagement.service.RedeemCodeService;

@RestController
@RequestMapping("/redeemCode")
public class RedeemCodeController {

  @Autowired
  private RedeemCodeService redeemCodeService;

  @GetMapping("/page")
  public IPage<RedeemCodeInfo> page(RedeemCodeInfoVO vo) {

    if (ObjectUtils.isEmpty(vo)) {
      throw new BizException(ResultMsg.OBJECT_IS_EMPTY.getMsg());
    }

    Page<RedeemCodeInfo> page = new Page<>(vo.getPageNo(), vo.getPageSize());

    return redeemCodeService.page(page, QueryBuild.redeemCodeQueryWrapper(vo));

  }

  @PostMapping("/add")
  public Result add(RedeemCodeInfoVO vo) throws IOException {
    if (vo.getNum() == null) {
      vo.setNum(1);
    }
    for (int i = 1; i <= vo.getNum(); i++) {
      RedeemCodeInfo info = new RedeemCodeInfo();
      UUID uuid = UUID.randomUUID();
      info.setRedeemCode(uuid.toString().replaceAll("-", "").toUpperCase());
      info.setUserRole(vo.getUserRole());
      info.setValidity(vo.getValidity());
      redeemCodeService.saveOrUpdate(info);
    }
    return Result.success();
  }

  @PostMapping("/update")
  @Transactional
  public Result update(RedeemCodeInfoVO vo) throws IOException {
    RedeemCodeInfo info = new RedeemCodeInfo();
    BeanUtil.copyProperties(vo, info);
    redeemCodeService.updateRedeemCode(info);
    return Result.success();
  }

  @GetMapping("/delete")
  public Result delete(RedeemCodeInfoVO vo) {

    if (ObjectUtils.isEmpty(vo) || ObjectUtils.isEmpty(vo.getId())) {
      throw new BizException(ResultMsg.OBJECT_IS_EMPTY.getMsg());
    }
    return Result.success(redeemCodeService.removeById(vo.getId()));

  }

  @GetMapping("/export")
  public ResponseEntity<InputStreamResource> exportRedeemCodes() {
    List<RedeemCodeInfo> redeemCodes = redeemCodeService.list(
            new LambdaQueryWrapper<RedeemCodeInfo>()
                    .select(RedeemCodeInfo::getId,
                            RedeemCodeInfo::getRedeemCode,
                            RedeemCodeInfo::getUserRole,
                            RedeemCodeInfo::getStatus,
                            RedeemCodeInfo::getValidity
                    )
                    .eq(RedeemCodeInfo::getStatus, RedeemCodeInfo.STATUS_NOTREDEEMED));
    StringBuilder data = new StringBuilder();
    for (RedeemCodeInfo code : redeemCodes) {
      String userRoleText = getUserRoleText(code.getUserRole());
      String statusText = getStatusText(code.getStatus());
      String validityDays = convertMinutesToDays(code.getValidity());

      data.append(code.getId()).append(" ")
              .append(code.getRedeemCode()).append(" ")
              .append(userRoleText).append(" ")
              .append(statusText).append(" ")
              .append(validityDays).append("\n");
    }
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data.toString().getBytes(StandardCharsets.UTF_8));
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Disposition", "attachment; filename=redeem_codes.txt");
    return new ResponseEntity<>(new InputStreamResource(byteArrayInputStream), headers, HttpStatus.OK);
  }

  private String getUserRoleText(int userRole) {
    switch (userRole) {
      case 1:
        return "普通会员";
      case 2:
        return "高级会员";
      default:
        return "未知角色";
    }
  }

  private String getStatusText(String status) {
    switch (status) {
      case "NotRedeemed":
        return "未兑换";
      case "AlreadyRedeemed":
        return "已兑换";
      default:
        return "未知状态";
    }
  }

  private String convertMinutesToDays(Long minutes) {
    return minutes / 1440.0+"";
  }

}
